home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 49
/
Amiga Format CD49 (2000-01-17)(Future Publishing)(GB)(Track 1 of 3)[!][issue 2000-02].iso
/
-serious-
/
graphics
/
gnuplot
/
gnuplot-3.7.1src
/
gnuplot-3.7.1
/
readline.c
< prev
next >
Wrap
C/C++ Source or Header
|
1999-11-29
|
28KB
|
1,106 lines
#ifndef lintnot DOS386 */
}
Sid = "$Id: readline.c,v 1.9.2.1 1999/08/19 14:38:07 lhecking Exp $";
#endif
/* GNUPLOT - readline.c */
/*[
* Copyright 1986 - 1993, 1998 Thomas Williams, Colin Kelley
*
* Permission to use, copy, and distribute this software and its
* documentation for any purpose with or without fee is hereby granted,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation.
*
* Permission to modify the software is granted, but not the right to
* distribute the complete modified source code. Modifications are to
* be distributed as patches to the released version. Permission to
* distribute binaries produced by compiling modified sources is granted,
* provided you
* 1. distribute the corresponding source modifications from the
* released version in the form of a patch file along with the binaries,
* 2. add special version identification to distinguish your version
* in addition to the base release version number,
* 3. provide your name and address as the primary contact for the
* support of your modified version, and
* 4. retain our contact information in regard to use of the base
* software.
* Permission to distribute the released version of the source code along
* with corresponding source modifications in the form of a patch file is
* granted with same provisions 2 through 4 for binary distributions.
*
* This software is provided "as is" without express or implied warranty
* to the extent permitted by applicable law.
]*/
/*
* AUTHORS
*
* Original Software:
* Tom Tkacik
*
* Msdos port and some enhancements:
* Gershon Elber and many others.
*
* In add_history(), do not store duplicated entries:
* Petr Mikulik
*/
#include <signal.h>
/* get prototype for alloc and gpfaralloc */
#include "plot.h"
#if defined(READLINE) && !defined(HAVE_LIBREADLINE)
/* a small portable version of GNU's readline
* this is not the BASH or GNU EMACS version of READLINE due to Copyleft
* restrictions
* do not need any terminal capabilities except backspace,
* and space overwrites a character
*/
/* NANO-EMACS line editing facility
* printable characters print as themselves (insert not overwrite)
* ^A moves to the beginning of the line
* ^B moves back a single character
* ^E moves to the end of the line
* ^F moves forward a single character
* ^K kills from current position to the end of line
* ^P moves back through history
* ^N moves forward through history
* ^H and DEL delete the previous character
* ^D deletes the current character, or EOF if line is empty
* ^L/^R redraw line in case it gets trashed
* ^U kills the entire line
* ^W kills last word
* LF and CR return the entire line regardless of the cursor postition
* EOF with an empty line returns (char *)NULL
*
* all other characters are ignored
*/
#ifdef __linux__
/* HBB: to get prototype for ioctl() */
# include <sys/ioctl.h>
#endif
/* replaces the previous klugde in configure */
#if defined(HAVE_TERMIOS_H) && defined(HAVE_TCGETATTR)
# define TERMIOS
#else /* not HAVE_TERMIOS_H && HAVE_TCGETATTR */
# ifdef HAVE_SGTTY_H
# define SGTTY
# endif
#endif /* not HAVE_TERMIOS_H && HAVE_TCGETATTR */
#if !defined(MSDOS) && !defined(ATARI) && !defined(MTOS) && !defined(_Windows) && !defined(DOS386) && !defined(OSK)
/*
* Set up structures using the proper include file
*/
# if defined(_IBMR2) || defined(alliant)
# define SGTTY
# endif
/* submitted by Francois.Dagorn@cicb.fr */
# ifdef SGTTY
# include <sgtty.h>
static struct sgttyb orig_termio, rl_termio;
/* define terminal control characters */
static struct tchars s_tchars;
# ifndef VERASE
# define VERASE 0
# endif /* not VERASE */
# ifndef VEOF
# define VEOF 1
# endif /* not VEOF */
# ifndef VKILL
# define VKILL 2
# endif /* not VKILL */
# ifdef TIOCGLTC /* available only with the 'new' line discipline */
static struct ltchars s_ltchars;
# ifndef VWERASE
# define VWERASE 3
# endif /* not VWERASE */
# ifndef VREPRINT
# define VREPRINT 4
# endif /* not VREPRINT */
# ifndef VSUSP
# define VSUSP 5
# endif /* not VSUP */
# endif /* TIOCGLTC */
# ifndef NCCS
# define NCCS 6
# endif /* not NCCS */
# else /* not SGTTY */
/* SIGTSTP defines job control
* if there is job control then we need termios.h instead of termio.h
* (Are there any systems with job control that use termio.h? I hope not.)
*/
# if defined(SIGTSTP) || defined(TERMIOS)
# ifndef TERMIOS
# define TERMIOS
# endif /* not TERMIOS */
# include <termios.h>
/* Added by Robert Eckardt, RobertE@beta.TP2.Ruhr-Uni-Bochum.de */
# ifdef ISC22
# ifndef ONOCR /* taken from sys/termio.h */
# define ONOCR 0000020 /* true at least for ISC 2.2 */
# endif /* not ONOCR */
# ifndef IUCLC
# define IUCLC 0001000
# endif /* not IUCLC */
# endif /* ISC22 */
# if !defined(IUCLC)
/* translate upper to lower case not supported */
# define IUCLC 0
# endif /* not IUCLC */
static struct termios orig_termio, rl_termio;
# else /* not SIGSTP || TERMIOS */
# include <termio.h>
static struct termio orig_termio, rl_termio;
/* termio defines NCC instead of NCCS */
# define NCCS NCC
# endif /* not SIGTSTP || TERMIOS */
# endif /* SGTTY */
/* ULTRIX defines VRPRNT instead of VREPRINT */
# if defined(VRPRNT) && !defined(VREPRINT)
# define VREPRINT VRPRNT
# endif /* VRPRNT */
/* define characters to use with our input character handler */
static char term_chars[NCCS];
static int term_set = 0; /* =1 if rl_termio set */
#define special_getc() ansi_getc()
static int ansi_getc __PROTO((void));
#else /* MSDOS or ATARI or MTOS or _Windows or DOS386 or OSK */
# ifdef _Windows
# include <windows.h>
# include "win/wtext.h"
# include "win/wgnuplib.h"
extern TW textwin;
# define TEXTUSER 0xf1
# define TEXTGNUPLOT 0xf0
# define special_getc() msdos_getch()
static char msdos_getch __PROTO((void)); /* HBB 980308: PROTO'ed it */
# endif /* _Windows */
# if defined(MSDOS) || defined(DOS386)
/* MSDOS specific stuff */
# ifdef DJGPP
# include <pc.h>
# endif /* DJGPP */
# ifdef __EMX__
# include <conio.h>
# endif /* __EMX__ */
# define special_getc() msdos_getch()
static char msdos_getch();
# endif /* MSDOS || DOS386 */
# ifdef OSK
# include <sgstat.h>
# include <modes.h>
# define STDIN 0
static int term_set = 0; /* =1 if new_settings is set */
static struct _sgs old_settings; /* old terminal settings */
static struct _sgs new_settings; /* new terminal settings */
# define special_getc() ansi_getc()
static int ansi_getc __PROTO((void));
/* On OS9 a '\n' is a character 13 and '\r' == '\n'. This gives troubles
here, so we need a new putc wich handles this correctly and print a
character 10 on each place we want a '\n'.
*/
# undef putc /* Undefine the macro for putc */
static int putc(c, fp)
char c;
FILE *fp;
{
write(fileno(fp), &c, 1);
if (c == '\012') { /* A normal ASCII '\n' */
c = '\r';
write(fileno(fp), &c, 1);
}
}
# endif /* OSK */
# if defined(ATARI) || defined(MTOS)
# define special_getc() tos_getch()
# endif /* ATARI || MTOS */
#endif /* MSDOS or ATARI or MTOS or _Windows or DOS386 or OSK */
#ifdef OS2
# if defined( special_getc )
# undef special_getc()
# endif /* special_getc */
# define special_getc() msdos_getch()
static char msdos_getch __PROTO((void)); /* HBB 980308: PROTO'ed it */
#endif /* OS2 */
/* initial size and increment of input line length */
#define MAXBUF 1024
/* ^H */
#define BACKSPACE 0x08
#define SPACE ' '
#ifdef OSK
# define NEWLINE '\012'
#else /* OSK */
# define NEWLINE '\n'
#endif /* not OSK */
struct hist {
char *line;
struct hist *prev;
struct hist *next;
};
static struct hist *history = NULL; /* no history yet */
static struct hist *cur_entry = NULL;
static char *cur_line; /* current contents of the line */
static int line_len = 0;
static int cur_pos = 0; /* current position of the cursor */
static int max_pos = 0; /* maximum character position */
static void fix_line __PROTO((void));
static void redraw_line __PROTO((char *prompt));
static void clear_line __PROTO((char *prompt));
static void clear_eoline __PROTO((void));
static void copy_line __PROTO((char *line));
static void set_termio __PROTO((void));
static void reset_termio __PROTO((void));
static int ansi_getc __PROTO((void));
static int user_putc __PROTO((int ch));
static int user_puts __PROTO((char *str));
static void backspace __PROTO((void));
static void extend_cur_line __PROTO((void));
/* user_putc and user_puts should be used in the place of
* fputc(ch,stderr) and fputs(str,stderr) for all output
* of user typed characters. This allows MS-Windows to
* display user input in a different color.
*/
static int user_putc(ch)
int ch;
{
int rv;
#ifdef _Windows
TextAttr(&textwin, TEXTUSER);
#endif
rv = fputc(ch, stderr);
#ifdef _Windows
TextAttr(&textwin, TEXTGNUPLOT);
#endif
return rv;
}
static int user_puts(str)
char *str;
{
int rv;
#ifdef _Windows
TextAttr(&textwin, TEXTUSER);
#endif
rv = fputs(str, stderr);
#ifdef _Windows
TextAttr(&textwin, TEXTGNUPLOT);
#endif
return rv;
}
/* This function provides a centralized non-destructive backspace capability
* M. Castro
*/
static void backspace()
{
user_putc(BACKSPACE);
}
static void extend_cur_line()
{
char *new_line;
/* extent input line length */
new_line = gp_realloc(cur_line, line_len + MAXBUF, NULL);
if (!new_line) {
reset_termio();
int_error("Can't extend readline length", NO_CARET);
}
cur_line = new_line;
line_len += MAXBUF;
FPRINTF((stderr, "\nextending readline length to %d chars\n", line_len));
}
char *
readline(prompt)
char *prompt;
{
int cur_char;
char *new_line;
/* start with a string of MAXBUF chars */
if (line_len != 0) {
free(cur_line);
line_len = 0;
}
cur_line = gp_alloc((unsigned long) MAXBUF, "readline");
line_len = MAXBUF;
/* set the termio so we can do our own input processing */
set_termio();
/* print the prompt */
fputs(prompt, stderr);
cur_line[0] = '\0';
cur_pos = 0;
max_pos = 0;
cur_entry = NULL;
/* get characters */
for (;;) {
cur_char = special_getc();
/*
* The #define CHARSET7BIT should be used when one encounters problems with
* 8bit characters that should not be entered on the commandline. I cannot
* think on any reasonable example where this could happen, but what do I know?
* After all, the unix world still ignores 8bit chars in most applications.
*
* Note that latin1 defines the chars 0x80-0x9f as control chars. For the
* benefit of Atari, MSDOS, Windows and NeXT I have decided to ignore this,
* since it would require more #ifs.
*
*/
#ifdef CHARSET7BIT
if (isprint(cur_char)) {
#else /* CHARSET7BIT */
if (isprint(cur_char) || (((unsigned char) cur_char > 0x7f) &&
cur_char != EOF)) {
#endif /* CHARSET7BIT */
int i;
if (max_pos + 1 >= line_len) {
extend_cur_line();
}
for (i = max_pos; i > cur_pos; i--) {
cur_line[i] = cur_line[i - 1];
}
user_putc(cur_char);
cur_line[cur_pos] = cur_char;
cur_pos += 1;
max_pos += 1;
if (cur_pos < max_pos)
fix_line();
cur_line[max_pos] = '\0';
/* else interpret unix terminal driver characters */
#ifdef VERASE
} else if (cur_char == term_chars[VERASE]) { /* DEL? */
if (cur_pos > 0) {
int i;
cur_pos -= 1;
backspace();
for (i = cur_pos; i < max_pos; i++)
cur_line[i] = cur_line[i + 1];
max_pos -= 1;
fix_line();
}
#endif /* VERASE */
#ifdef VEOF
} else if (cur_char == term_chars[VEOF]) { /* ^D? */
if (max_pos == 0) {
reset_termio();
return ((char *) NULL);
}
if ((cur_pos < max_pos) && (cur_char == 004)) { /* ^D */
int i;
for (i = cur_pos; i < max_pos; i++)
cur_line[i] = cur_line[i + 1];
max_pos -= 1;
fix_line();
}
#endif /* VEOF */
#ifdef VKILL
} else if (cur_char == term_chars[VKILL]) { /* ^U? */
clear_line(prompt);
#endif /* VKILL */
#ifdef VWERASE
} else if (cur_char == term_chars[VWERASE]) { /* ^W? */
while ((cur_pos > 0) &&
(cur_line[cur_pos - 1] == SPACE)) {
cur_pos -= 1;
backspace();
}
while ((cur_pos > 0) &&
(cur_line[cur_pos - 1] != SPACE)) {
cur_pos -= 1;
backspace();
}
clear_eoline();
max_pos = cur_pos;
#endif /* VWERASE */
#ifdef VREPRINT
} else if (cur_char == term_chars[VREPRINT]) { /* ^R? */
putc(NEWLINE, stderr); /* go to a fresh line */
redraw_line(prompt);
#endif /* VREPRINT */
#ifdef VSUSP
} else if (cur_char == term_chars[VSUSP]) {
reset_termio();
kill(0, SIGTSTP);
/* process stops here */
set_termio();
/* print the prompt */
redraw_line(prompt);
#endif /* VSUSP */
} else {
/* do normal editing commands */
/* some of these are also done above */
int i;
switch (cur_char) {
case EOF:
reset_termio();
return ((char *) NULL);
case 001: /* ^A */
while (cur_pos > 0) {
cur_pos -= 1;
backspace();
}
break;
case 002: /* ^B */
if (cur_pos > 0) {
cur_pos -= 1;
backspace();
}
break;
case 005: /* ^E */
while (cur_pos < max_pos) {
user_putc(cur_line[cur_pos]);
cur_pos += 1;
}
break;
case 006: /* ^F */
if (cur_pos < max_pos) {
user_putc(cur_line[cur_pos]);
cur_pos += 1;
}
break;
case 013: /* ^K */
clear_eoline();
max_pos = cur_pos;
break;
case 020: /* ^P */
if (history != NULL) {
if (cur_entry == NULL) {
cur_entry = history;
clear_line(prompt);
copy_line(cur_entry->line);
} else if (cur_entry->prev != NULL) {
cur_entry = cur_entry->prev;
clear_line(prompt);
copy_line(cur_entry->line);
}
}
break;
case 016: /* ^N */
if (cur_entry != NULL) {
cur_entry = cur_entry->next;
clear_line(prompt);
if (cur_entry != NULL)
copy_line(cur_entry->line);
else
cur_pos = max_pos = 0;
}
break;
case 014: /* ^L */
case 022: /* ^R */
putc(NEWLINE, stderr); /* go to a fresh line */
redraw_line(prompt);
break;
case 0177: /* DEL */
case 010: /* ^H */
if (cur_pos > 0) {
cur_pos -= 1;
backspace();
for (i = cur_pos; i < max_pos; i++)
cur_line[i] = cur_line[i + 1];
max_pos -= 1;
fix_line();
}
break;
case 004: /* ^D */
if (max_pos == 0) {
reset_termio();
return ((char *) NULL);
}
if (cur_pos < max_pos) {
for (i = cur_pos; i < max_pos; i++)
cur_line[i] = cur_line[i + 1];
max_pos -= 1;
fix_line();
}
break;
case 025: /* ^U */
clear_line(prompt);
break;
case 027: /* ^W */
while ((cur_pos > 0) &&
(cur_line[cur_pos - 1] == SPACE)) {
cur_pos -= 1;
backspace();
}
while ((cur_pos > 0) &&
(cur_line[cur_pos - 1] != SPACE)) {
cur_pos -= 1;
backspace();
}
clear_eoline();
max_pos = cur_pos;
break;
case '\n': /* ^J */
#ifndef OSK
case '\r': /* ^M */
#endif
cur_line[max_pos + 1] = '\0';
#ifdef OS2
while (cur_pos < max_pos) {
user_putc(cur_line[cur_pos]);
cur_pos += 1;
}
#endif
putc(NEWLINE, stderr);
/* Shrink the block down to fit the string ?
* if the alloc fails, we still own block at cur_line,
* but this shouldn't really fail.
*/
new_line = (char *) gp_realloc(cur_line, (unsigned long) (strlen(cur_line) + 1), "line resize");
if (new_line)
cur_line = new_line;
/* else we just hang on to what we had - it's not a problem */
line_len = 0;
FPRINTF((stderr, "Resizing input line to %d chars\n", strlen(cur_line)));
reset_termio();
return (cur_line);
default:
break;
}
}
}
}
/* fix up the line from cur_pos to max_pos
* do not need any terminal capabilities except backspace,
* and space overwrites a character
*/
static void fix_line()
{
int i;
/* write tail of string */
for (i = cur_pos; i < max_pos; i++)
user_putc(cur_line[i]);
/* write a space at the end of the line in case we deleted one */
user_putc(SPACE);
/* backup to original position */
for (i = max_pos + 1; i > cur_pos; i--)
backspace();
}
/* redraw the entire line, putting the cursor where it belongs */
static void redraw_line(prompt)
char *prompt;
{
int i;
fputs(prompt, stderr);
user_puts(cur_line);
/* put the cursor where it belongs */
for (i = max_pos; i > cur_pos; i--)
backspace();
}
/* clear cur_line and the screen line */
static void clear_line(prompt)
char *prompt;
{
int i;
for (i = 0; i < max_pos; i++)
cur_line[i] = '\0';
for (i = cur_pos; i > 0; i--)
backspace();
for (i = 0; i < max_pos; i++)
putc(SPACE, stderr);
putc('\r', stderr);
fputs(prompt, stderr);
cur_pos = 0;
max_pos = 0;
}
/* clear to end of line and the screen end of line */
static void clear_eoline()
{
int i;
for (i = cur_pos; i < max_pos; i++)
cur_line[i] = '\0';
for (i = cur_pos; i < max_pos; i++)
putc(SPACE, stderr);
for (i = cur_pos; i < max_pos; i++)
backspace();
}
/* copy line to cur_line, draw it and set cur_pos and max_pos */
static void copy_line(line)
char *line;
{
while (strlen(line) + 1 > line_len) {
extend_cur_line();
}
strcpy(cur_line, line);
user_puts(cur_line);
cur_pos = max_pos = strlen(cur_line);
}
/* add line to the history */
void add_history(line)
char *line;
{
struct hist *entry;
entry = history;
while (entry != NULL) {
/* Don't store duplicate entries */
if (!strcmp(entry->line, line)) {
/* cmd lines are equal, relink entry that was found last */
if (entry->next == NULL) {
/* previous command repeated, no change */
return;
}
if (entry->prev == NULL) {
/* current cmd line equals the first in the history */
(entry->next)->prev = NULL;
history->next = entry;
entry->prev = history;
entry->next = NULL;
history = entry;
return;
}
/* bridge over entry's vacancy, then move it to the end */
(entry->prev)->next = entry->next;
(entry->next)->prev = entry->prev;
entry->prev = history;
history->next = entry;
entry->next = NULL;
history = entry;
return;
}
entry = entry->prev;
} /* end of not-storing duplicated entries */
entry = (struct hist *) gp_alloc((unsigned long) sizeof(struct hist), "history");
entry->line = gp_alloc((unsigned long) (strlen(line) + 1), "history");
strcpy(entry->line, line);
entry->prev = history;
entry->next = NULL;
if (history != NULL) {
history->next = entry;
}
history = entry;
}
/* Convert ANSI arrow keys to control characters */
static int ansi_getc()
{
int c = getc(stdin);
if (c == 033) {
c = getc(stdin); /* check for CSI */
if (c == '[') {
c = getc(stdin); /* get command character */
switch (c) {
case 'D': /* left arrow key */
c = 002;
break;
case 'C': /* right arrow key */
c = 006;
break;
case 'A': /* up arrow key */
c = 020;
break;
case 'B': /* down arrow key */
c = 016;
break;
}
}
}
return c;
}
#if defined(MSDOS) || defined(_Windows) || defined(DOS386) || defined(OS2)
/* Convert Arrow keystrokes to Control characters: */
static char msdos_getch()
{
#ifdef DJGPP
char c;
int ch = getkey();
c = (ch & 0xff00) ? 0 : ch & 0xff;
#else /* not DJGPP */
# ifdef OS2
char c = getc(stdin);
# else /* not OS2 */
char c = getch();
# endif /* not OS2 */
#endif /* not DJGPP */
if (c == 0) {
#ifdef DJGPP
c = ch & 0xff;
#else /* not DJGPP */
# ifdef OS2
c = getc(stdin);
# else /* not OS2 */
c = getch(); /* Get the extended code. */
# endif /* not OS2 */
#endif /* not DJGPP */
switch (c) {
case 75: /* Left Arrow. */
c = 002;
break;
case 77: /* Right Arrow. */
c = 006;
break;
case 72: /* Up Arrow. */
c = 020;
break;
case 80: /* Down Arrow. */
c = 016;
break;
case 115: /* Ctl Left Arrow. */
case 71: /* Home */
c = 001;
break;
case 116: /* Ctl Right Arrow. */
case 79: /* End */
c = 005;
break;
case 83: /* Delete */
c = 004;
break;
default:
c = 0;
break;
}
} else if (c == 033) { /* ESC */
c = 025;
}
return c;
}
#endif /* MSDOS || _Windows || DOS386 || OS2 */
#if defined(ATARI) || defined(MTOS)
/* Convert Arrow keystrokes to Control characters: TOS version */
long poll_events(int); /* from term/atariaes.trm */
/* this function is used in help.c as well. this means that the
* program doesn't work without -DREADLINE (which would be the case
* if help.c didn't use it as well, since no events would be processed)
*/
char tos_getch()
{
long rawkey;
char c;
int scan_code;
static int in_help = 0;
if (strcmp(term->name, "atari") == 0)
poll_events(0);
if (in_help) {
switch (in_help) {
case 1:
case 5:
in_help++;
return 'e';
case 2:
case 6:
in_help++;
return 'l';
case 3:
case 7:
in_help++;
return 'p';
case 4:
in_help = 0;
return 0x0d;
case 8:
in_help = 0;
return ' ';
}
}
if (strcmp(term->name, "atari") == 0) {
do {
if (Bconstat(2))
rawkey = Cnecin();
else
rawkey = poll_events(1);
} while (rawkey == 0);
} else
rawkey = Cnecin();
c = (char) rawkey;
scan_code = ((int) (rawkey >> 16)) & 0xff; /* get the scancode */
if (Kbshift(-1) & 0x00000007)
scan_code |= 0x80; /* shift or control ? */
switch (scan_code) {
case 0x62: /* HELP */
case 0xe2: /* shift HELP */
if (max_pos == 0) {
if (scan_code == 0x62) {
in_help = 1;
} else {
in_help = 5;
}
return 'h';
} else {
return 0;
}
case 0x48: /* Up Arrow */
return 0x10; /* ^P */
case 0x50: /* Down Arrow */
return 0x0e; /* ^N */
case 0x4b: /* Left Arrow */
return 0x02; /* ^B */
case 0x4d: /* Right Arrow */
return 0x06; /* ^F */
case 0xcb: /* Shift Left Arrow */
case 0xf3: /* Ctrl Left Arrow (TOS-bug ?) */
case 0x47: /* Home */
return 0x01; /* ^A */
case 0xcd: /* Shift Right Arrow */
case 0xf4: /* Ctrl Right Arrow (TOS-bug ?) */
case 0xc7: /* Shift Home */
case 0xf7: /* Ctrl Home */
return 0x05; /* ^E */
case 0x61: /* Undo - redraw line */
return 0x0c; /* ^L */
default:
if (c == 0x1b)
return 0x15; /* ESC becomes ^U */
if (c == 0x7f)
return 0x04; /* Del becomes ^D */
break;
}
return c;
}
#endif /* ATARI || MTOS */
/* set termio so we can do our own input processing */
static void set_termio()
{
#if !defined(MSDOS) && !defined(ATARI) && !defined(MTOS) && !defined(_Windows) && !defined(DOS386)
/* set termio so we can do our own input processing */
/* and save the old terminal modes so we can reset them later */
if (term_set == 0) {
/*
* Get terminal modes.
*/
# ifndef OSK
# ifdef SGTTY
ioctl(0, TIOCGETP, &orig_termio);
# else /* not SGTTY */
# ifdef TERMIOS
# ifdef TCGETS
ioctl(0, TCGETS, &orig_termio);
# else /* not TCGETS */
tcgetattr(0, &orig_termio);
# endif /* not TCGETS */
# else /* not TERMIOS */
ioctl(0, TCGETA, &orig_termio);
# endif /* TERMIOS */
# endif /* not SGTTY */
# else /* OSK */
setbuf(stdin, (char *) 0); /* Make stdin and stdout unbuffered */
setbuf(stderr, (char *) 0);
_gs_opt(STDIN, &new_settings);
# endif /* OSK */
/*
* Save terminal modes
*/
# ifndef OSK
rl_termio = orig_termio;
# else /* OSK */
_gs_opt(STDIN, &old_settings);
# endif /* OSK */
/*
* Set the modes to the way we want them
* and save our input special characters
*/
# ifndef OSK
# ifdef SGTTY
rl_termio.sg_flags |= CBREAK;
rl_termio.sg_flags &= ~(ECHO | XTABS);
ioctl(0, TIOCSETN, &rl_termio);
ioctl(0, TIOCGETC, &s_tchars);
term_chars[VERASE] = orig_termio.sg_erase;
term_chars[VEOF] = s_tchars.t_eofc;
term_chars[VKILL] = orig_termio.sg_kill;
# ifdef TIOCGLTC
ioctl(0, TIOCGLTC, &s_ltchars);
term_chars[VWERASE] = s_ltchars.t_werasc;
term_chars[VREPRINT] = s_ltchars.t_rprntc;
term_chars[VSUSP] = s_ltchars.t_suspc;
/* disable suspending process on ^Z */
s_ltchars.t_suspc = 0;
ioctl(0, TIOCSLTC, &s_ltchars);
# endif /* TIOCGLTC */
# else /* not SGTTY */
rl_termio.c_iflag &= ~(BRKINT | PARMRK | INPCK | IUCLC | IXON | IXOFF);
rl_termio.c_iflag |= (IGNBRK | IGNPAR);
/* rl_termio.c_oflag &= ~(ONOCR); Costas Sphocleous Irvine,CA */
rl_termio.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | NOFLSH);
# ifdef OS2
/* for emx: remove default terminal processing */
rl_termio.c_lflag &= ~(IDEFAULT);
# endif /* OS2 */
rl_termio.c_lflag |= (ISIG);
rl_termio.c_cc[VMIN] = 1;
rl_termio.c_cc[VTIME] = 0;
# ifndef VWERASE
# define VWERASE 3
# endif /* VWERASE */
term_chars[VERASE] = orig_termio.c_cc[VERASE];
term_chars[VEOF] = orig_termio.c_cc[VEOF];
term_chars[VKILL] = orig_termio.c_cc[VKILL];
# ifdef TERMIOS
term_chars[VWERASE] = orig_termio.c_cc[VWERASE];
# ifdef VREPRINT
term_chars[VREPRINT] = orig_termio.c_cc[VREPRINT];
# else /* not VREPRINT */
# ifdef VRPRNT
term_chars[VRPRNT] = orig_termio.c_cc[VRPRNT];
# endif /* VRPRNT */
# endif /* not VREPRINT */
term_chars[VSUSP] = orig_termio.c_cc[VSUSP];
/* disable suspending process on ^Z */
rl_termio.c_cc[VSUSP] = 0;
# endif /* TERMIOS */
# endif /* not SGTTY */
# else /* OSK */
new_settings._sgs_echo = 0; /* switch off terminal echo */
new_settings._sgs_pause = 0; /* inhibit page pause */
new_settings._sgs_eofch = 0; /* inhibit eof */
new_settings._sgs_kbich = 0; /* inhibit ^C */
new_settings._sgs_kbach = 0; /* inhibit ^E */
# endif /* OSK */
/*
* Set the new terminal modes.
*/
# ifndef OSK
# ifdef SGTTY
ioctl(0, TIOCSLTC, &s_ltchars);
# else /* not SGTTY */
# ifdef TERMIOS
# ifdef TCSETSW
ioctl(0, TCSETSW, &rl_termio);
# else /* not TCSETSW */
tcsetattr(0, TCSADRAIN, &rl_termio);
# endif /* not TCSETSW */
# else /* not TERMIOS */
ioctl(0, TCSETAW, &rl_termio);
# endif /* not TERMIOS */
# endif /* not SGTTY */
# else /* OSK */
_ss_opt(STDIN, &new_settings);
# endif /* OSK */
term_set = 1;
}
#endif /* not MSDOS && not ATARI && not MTOS && not _Windows && not DOS386 */
}
static void reset_termio()
{
#if !defined(MSDOS) && !defined(ATARI) && !defined(MTOS) && !defined(_Windows) && !defined(DOS386)
/* reset saved terminal modes */
if (term_set == 1) {
# ifndef OSK
# ifdef SGTTY
ioctl(0, TIOCSETN, &orig_termio);
# ifdef TIOCGLTC
/* enable suspending process on ^Z */
s_ltchars.t_suspc = term_chars[VSUSP];
ioctl(0, TIOCSLTC, &s_ltchars);
# endif /* TIOCGLTC */
# else /* not SGTTY */
# ifdef TERMIOS
# ifdef TCSETSW
ioctl(0, TCSETSW, &orig_termio);
# else /* not TCSETSW */
tcsetattr(0, TCSADRAIN, &orig_termio);
# endif /* not TCSETSW */
# else /* not TERMIOS */
ioctl(0, TCSETAW, &orig_termio);
# endif /* TERMIOS */
# endif /* not SGTTY */
# else /* OSK */
_ss_opt(STDIN, &old_settings);
# endif /* OSK */
term_set = 0;
}
#endif /* not MSDOS && not ATARI && not MTOS && not _Windows && not DOS386 */
}
#endif /* READLINE && not HAVE_LIBREADLINE */